// Copyright 2007 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lichen.services.binding;

import java.util.ArrayList;
import java.util.List;

import org.apache.tapestry.Binding;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.TapestryConstants;
import org.apache.tapestry.ioc.Location;
import org.apache.tapestry.services.BindingFactory;
import org.apache.tapestry.services.BindingSource;

/**
 * 一个list的binding factory,目前的T5.0.5还不支持数组方式的参数申明.
 * Implementation of the list: binding prefix -- we parse list of bindings
 * and generate delegate bindings for each element<br>
 * default binding is prop, except when surrounded with '' or is a numeric value ([0-9.]*)
 * <pre>
 *  &lt;T:ActionLink page="Product" context="list:product.id,'view'"&gt;View&lt;/T:ActionLink&gt;
 *  &lt;T:ActionLink page="Product" context="list:product.id,'edit'"&gt;Edit&lt;/T:ActionLink&gt;
 * </pre>
 * 
 * see:<br>
 *  http://wiki.apache.org/tapestry/Tapestry5HowToAddBindingPrefix
 *  
 * @author jcai
 * @version $Revision: 7 $
 * @since 0.0.1
 */
public class ListBindingFactory implements BindingFactory {
    private final BindingSource _bindingSource;

    public ListBindingFactory(BindingSource source){
        this._bindingSource = source;
    }
    
    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
            String expression, Location location)
    {
        List<Binding> delegates = new ArrayList<Binding>();
        String[] bindingNames = expression.split(",");
        
        for (String bindingName : bindingNames){
            String defaultBinding = TapestryConstants.LITERAL_BINDING_PREFIX;
            
            if(bindingName.charAt(0) == '\''){
                //translate "'something'" to "literal:something"
                bindingName = bindingName.substring(1,bindingName.length()-1);

            }else{
                //if value is numeric, we leave literal binding prefix as default
                for (int i = 0; i < bindingName.length(); i++) {
                    char ch = bindingName.charAt(i);
                    if(ch != '.' && !Character.isDigit(ch)){
                        defaultBinding = TapestryConstants.PROP_BINDING_PREFIX; 
                        break;
                    }
                }
            }

            delegates.add(_bindingSource.newBinding(description, container, component, defaultBinding, bindingName, location));
        }
        
        return new ListBinding(delegates);
    }
}
